package com.mrogrape.notepad.ui.filechooser;

import java.awt.Component;
import java.io.File;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import com.mrogrape.notepad.resource.Strings;
import com.mrogrape.notepad.ui.editor.ContentType;
import com.mrogrape.util.StringUtils;


/**
 * 自定义的文件选择器，默认情况下使用此文件选择器只能选择文件。
 * 
 * @author 110046
 *
 */
public class NotepadFileChooser extends JFileChooser{

    /** serialVersionUID */
    private static final long serialVersionUID = -1L;

    /**
     * {@inheritDoc}}
     */
    public NotepadFileChooser() {

	super();
	// Select Files Only
	this.setFileSelectionMode(JFileChooser.FILES_ONLY);
    }

    /**
     * 显示一个“打开文件”对话框并选择一个文件。
     * 
     * @param parent      对话框所依托的组件，可以为空
     * @param Accessory   accessory 组件，可以为空
     * @param title       对话框的标题，如果为null则默认显示“Open”
     * @param file        默认选择的文件，或所在文件夹，可以为null。
     * @param acceptAll   是否显示“全部文件”文件过滤器。
     * @param defaultType 默认选择该内容的文件过滤器，可以为空。
     * @param accepted    所允许选择的类型，可以为空。
     * @return 选择的文件，如果用户点击取消则返回null。
     */
    public File showOpenSingleFileDialog(Component parent, JComponent accessory,
	    String title, File file, boolean acceptAll,
	    ContentType defaultType, ContentType... accepted) {

	// Initialize
	this.setAccessory(accessory);
	this.setDialogTitle(title == null?Strings.Label.OPEN_FILE:title);
	this.setMultiSelectionEnabled(false);
	this.setAcceptAllFileFilterUsed(acceptAll);
	this.setFileSelectionMode(JFileChooser.FILES_ONLY);

	if(file != null && file.isDirectory()){
	    this.setCurrentDirectory(file);
	}else{
	    this.setSelectedFile(file);
	}

	this.resetChoosableFileFilters();

	if(accepted != null){
	    for(ContentType c : accepted){
		this.addChoosableFileFilter(this.getFileFilter(c));
	    }
	}

	if(defaultType != null){
	    FileFilter selectedFilter = this.getFileFilter(defaultType);
	    this.setFileFilter(selectedFilter);
	}
	else if(acceptAll){
		 this.setFileFilter(this.getAcceptAllFileFilter());
	}
	else{
		this.setFileFilter(this.getFileFilter(accepted[0]));
	}

	int result = this.showOpenDialog(parent);
	if(result == JFileChooser.APPROVE_OPTION){

	    return this.getSelectedFile();
	}

	return null;
    }

    /**
     * 显示一个“打开文件”对话框并选择多个文件。
     * 
     * @param parent      对话框所依托的组件，可以为空
     * @param Accessory   accessory 组件，可以为空
     * @param title       对话框的标题，如果为null则默认显示“Open”
     * @param file        默认选择的文件，或所在文件夹，可以为null。
     * @param acceptAll   是否显示“全部文件”文件过滤器。
     * @param defaultType 默认选择该内容的文件过滤器，可以为空。
     * @param accepted    所允许选择的类型，可以为空。
     * @return 选择的文件，如果用户点击取消则返回null。
     */
    public File[] showOpenMultiFileDialog(Component parent, JComponent accessory,
	    String title, File file, boolean acceptAll,
	    ContentType defaultType, ContentType... accepted){

	// Initialize
	this.setAccessory(accessory);
	this.setDialogTitle(title == null?Strings.Label.OPEN_FILE:title);
	this.setAcceptAllFileFilterUsed(acceptAll);
	this.setMultiSelectionEnabled(true);
	this.setFileSelectionMode(JFileChooser.FILES_ONLY);

	if(file != null && file.isDirectory()){
	    this.setCurrentDirectory(file);
	}else{
	    this.setSelectedFile(file);
	}

	this.resetChoosableFileFilters();

	if(accepted != null){
	    for(ContentType c : accepted){
		this.addChoosableFileFilter(this.getFileFilter(c));
	    }
	}

	if(defaultType != null){
	    FileFilter selectedFilter = this.getFileFilter(defaultType);
	    this.setFileFilter(selectedFilter);
	}
	else if(acceptAll){
		 this.setFileFilter(this.getAcceptAllFileFilter());
	}
	else{
		this.setFileFilter(this.getFileFilter(accepted[0]));
	}

	int result = this.showOpenDialog(parent);
	if(result == JFileChooser.APPROVE_OPTION){

	    return this.getSelectedFiles();
	}

	return null;
    }


    public File showSaveFileDialog(Component parent, JComponent accessory,
	    String title, File file, boolean acceptAll, boolean keepExt,
	    ContentType defaultType, ContentType... accepted){

	// Initialize
	this.setAccessory(accessory);
	this.setDialogTitle(title == null?Strings.Label.SAVE_FILE:title);
	this.setMultiSelectionEnabled(false);
	this.setAcceptAllFileFilterUsed(acceptAll);
	this.setFileSelectionMode(JFileChooser.FILES_ONLY);

	if(file != null && file.isDirectory()){
	    this.setCurrentDirectory(file);
	}else{
	    this.setSelectedFile(file);
	}

	this.resetChoosableFileFilters();

	if(accepted != null){
	    for(ContentType c : accepted){
		this.addChoosableFileFilter(this.getFileFilter(c));
	    }
	}

	if(defaultType != null){
	    FileFilter selectedFilter = this.getFileFilter(defaultType);
	    this.setFileFilter(selectedFilter);
	}

	int result = this.showOpenDialog(parent);
	if(result == JFileChooser.APPROVE_OPTION){

	    File selectedFile = this.getSelectedFile();
	    String path = selectedFile.getAbsolutePath();
	    ContentType selectedFilterType = ((ContentTypeFileFilter)this.getFileFilter()).getContentType();
	    if (!selectedFile.exists() && keepExt && !path.toLowerCase(Locale.ENGLISH).endsWith("." + selectedFilterType.getPreferredFileExtension())) {

		path = path + "." + selectedFilterType.getPreferredFileExtension();
		selectedFile = new File(path);
	    }

	    return selectedFile;
	}

	return null;
    }


    /**
     * 显示选择文件对话框。
     * 
     * @param parent
     * @param title
     * @return
     */
    public OpenOption showOpenFileChooser(Component parent, String title){

	if(this.openOptionPane == null){
	    this.openOptionPane = new OpenOptionPane();
	}
	this.setAccessory(this.openOptionPane);
	this.setDialogTitle(StringUtils.isEmpty(title)?"Open":title);

	int re = this.showOpenDialog(parent);

	if(re == JFileChooser.APPROVE_OPTION){

	    OpenOption option = new OpenOption();
	    option.setCharset(this.openOptionPane.getCharset());
	    option.setFile(this.getSelectedFile());
	    return option;
	}

	return null;
    }

    public SaveOption showSaveFileChooser(Component parent, String title, String currentCharset){

	if(this.saveOptionPane == null){
	    this.saveOptionPane = new SaveOptionPane(currentCharset);
	}
	else {
	    this.saveOptionPane.setCharset(currentCharset);
	}

	this.setAccessory(this.saveOptionPane);
	this.setDialogTitle(StringUtils.isEmpty(title)?"Save":title);

	int re = this.showSaveDialog(parent);
	if(re == JFileChooser.APPROVE_OPTION){

	    SaveOption opt = new SaveOption();
	    opt.setCharset(this.saveOptionPane.getCharset());
	    opt.setFile(this.getSelectedFile());
	    return opt;
	}

	return null;
    }

    private OpenOptionPane openOptionPane = null;
    private SaveOptionPane saveOptionPane = null;

    private FileFilter getFileFilter(ContentType c){

	FileFilter filter = this.filterMap.get(c.getMimeType());
	if(filter == null){

	    filter = new ContentTypeFileFilter(c);
	    this.filterMap.put(c.getMimeType(), filter);
	}

	return filter;
    }

    private Map<String,FileFilter> filterMap = new HashMap<String,FileFilter>();

    public static void main(String[] args){

	NotepadFileChooser chooser = new NotepadFileChooser();

	System.out.println(chooser.showOpenSingleFileDialog(null, null, "Test Open", new File("e:/download"), true, ContentType.JAVA, (ContentType[])null));
    }

}
